package com.henghe.frame.ddl.util.postgres;

import com.henghe.frame.common.util.PattenUtil;
import com.henghe.frame.ddl.constant.DdlConstant;
import com.henghe.frame.ddl.pojo.ColumnVo;
import com.henghe.frame.ddl.pojo.TableColumnEntity;
import com.henghe.frame.ddl.pojo.TableEntity;
import com.henghe.frame.ddl.pojo.postgres.PostgresTableEntity;
import com.henghe.frame.ddl.util.DbUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Description:
 * Author: LiuWenQing
 * Datetime: 2024/9/29 09:35
 */
@Slf4j
public class PostgresDbUtil extends DbUtil {

    public static List<Class> generatorClasses = Arrays.asList(int.class,
            Integer.class, String.class, Long.class, long.class, BigDecimal.class, Date.class, LocalDateTime.class);


    /**
     * 扫描注解后，获取表实体集合
     *
     * @param path
     * @return
     */
    public static List<TableEntity> getCodeDb(String path, String schema, String dbName) {
        return searchPackageEntities(path, DdlConstant.PG, null, generatorClasses, schema, dbName);
    }

    /**
     * 检查是否相等
     *
     * @param tableColumnEntity
     * @param columnVo
     * @return
     */
    public static Boolean columnCheck(TableColumnEntity tableColumnEntity, ColumnVo columnVo) {
        // 判断字段类型
        if (tableColumnEntity.getType().equals("varchar") &&
                !(DdlConstant.PostgresStrTypes.contains(columnVo.getDataType().trim())))
            return Boolean.FALSE;
        if(DdlConstant.PostgresNumberTypes.contains(tableColumnEntity.getType()) &&
            !Arrays.asList("integer","bigint").contains(columnVo.getDataType())){
            return Boolean.FALSE;
        }
//        else{
//            if (!tableColumnEntity.getType().toLowerCase().equals(columnVo.getDataType().toLowerCase()))
//                return Boolean.FALSE;
//        }
        // 判断是否可为空
//        if (!tableColumnEntity.getIsNotNull().equals(columnVo.getIsNotNull()))
//            return Boolean.FALSE;

        // 判断默认值
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())
                && !tableColumnEntity.getDefaultValue().equals(columnVo.getDefaultValue()))
            return Boolean.FALSE;

        // 判断注释
//        if (StringUtils.isNotEmpty(tableColumnEntity.getComment())
//                && !tableColumnEntity.getComment().equals(columnVo.getComment()))
//            return Boolean.FALSE;

        return Boolean.TRUE;
    }


    /**
     * 生成postgres建表语句
     *
     * @param postgresTableEntity
     * @return
     */
    public static String generateTable(PostgresTableEntity postgresTableEntity) {
        StringBuffer stringBuffer = new StringBuffer("");
        stringBuffer.append("CREATE TABLE \"" + postgresTableEntity.getSchema() + "\".\"" + postgresTableEntity.getTableName() + "\" (");
        List<TableColumnEntity> columns = postgresTableEntity.getColumns();
        TableColumnEntity idColumn = columns.stream().filter(e -> e.getIsPrimaryKey() == true).findAny().orElse(null);
        if (idColumn == null)
            return "";
        for (TableColumnEntity column : columns) {
            stringBuffer.append("\"" + column.getName() + "\" " + column.getType());
            if (column.getIsNotNull() != null && column.getIsNotNull())
                stringBuffer.append(" NOT NULL");
            if (StringUtils.isNotEmpty(column.getDefaultValue()))
                stringBuffer.append(" DEFAULT " + column.getDefaultValue());
            stringBuffer.append(",");
        }
        String pkName = postgresTableEntity.getTableName() + "_pkey";
        stringBuffer.append("CONSTRAINT \"" + pkName + "\"  PRIMARY KEY (\"" + idColumn.getName() + "\")");
        stringBuffer.append(")");
        return stringBuffer.toString();
    }

    /**
     * 生成postgres授权语句
     *
     * @param postgresTableEntity
     * @return
     */
    public static String generateOwner(PostgresTableEntity postgresTableEntity) {
        StringBuffer stringBuffer = new StringBuffer("");
        stringBuffer.append("ALTER TABLE \"" + postgresTableEntity.getSchema() + "\".\"" + postgresTableEntity.getTableName() + "\" OWNER TO \"" + postgresTableEntity.getDbName() + "\"");
        return stringBuffer.toString();
    }

    /**
     * 生成postgres注释
     *
     * @param postgresTableEntity
     * @return
     */
    public static List<String> generateComment(PostgresTableEntity postgresTableEntity) {
        List<TableColumnEntity> columns = postgresTableEntity.getColumns();
        List<TableColumnEntity> collect = columns.stream().filter(e -> StringUtils.isNotEmpty(e.getComment())).collect(Collectors.toList());
        List<String> comments = new ArrayList<>();
        if (!collect.isEmpty()) {
            for (TableColumnEntity tableColumnEntity : collect) {
                String s = "";
                String comment = tableColumnEntity.getComment();
                if (StringUtils.isNotEmpty(comment)) {
                    s += "COMMENT ON COLUMN \"" + postgresTableEntity.getSchema() + "\".\"" + postgresTableEntity.getTableName() + "\".\"" + tableColumnEntity.getName() + "\" IS '" + tableColumnEntity.getComment() + "'";
                }
                if (StringUtils.isNotEmpty(s))
                    comments.add(s);
            }
        }
        return comments;
    }

    /**
     * 新增字段
     *
     * @param tableColumnEntity
     * @param tableName
     * @return
     */
    public static String addColumn(TableColumnEntity tableColumnEntity, String tableName) {
        String sql = "alter table " + tableName + " ADD COLUMN " + tableColumnEntity.getName() + " " + tableColumnEntity.getType() + " ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getLength()))
            sql += "(" + tableColumnEntity.getLength() + ") ";
//        if (tableColumnEntity.getIsNotNull() != null && tableColumnEntity.getIsNotNull())
//            sql += " not null ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())) {
            String valueStr = tableColumnEntity.getDefaultValue();
            Boolean needBrackets;
            if (valueStr.contains(".")) {
                needBrackets = !PattenUtil.isAllDigits(valueStr.replaceAll(".", ""));
            } else {
                needBrackets = !PattenUtil.isAllDigits(valueStr);
            }
            sql += "DEFAULT " + (needBrackets ? ("(" + valueStr + ")") : (valueStr)) + " ";
        }
        return sql;
    }


    /**
     * 修改字段
     * @param tableColumnEntity
     * @param tableName
     * @return
     */
    public static String updateColumn(TableColumnEntity tableColumnEntity, String tableName) {
        String sql = "alter table "+tableName+" alter column "+tableColumnEntity.getName() +" type "+tableColumnEntity.getType()+" ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getLength()))
            sql += "(" + tableColumnEntity.getLength() + ") ";
//        if (!tableColumnEntity.getName().equals("id") && tableColumnEntity.getIsNotNull() != null && tableColumnEntity.getIsNotNull())
//            sql += " not null ";
        if (StringUtils.isNotEmpty(tableColumnEntity.getDefaultValue())) {
            String valueStr = tableColumnEntity.getDefaultValue();
            Boolean needBrackets;
            if (valueStr.contains(".")) {
                needBrackets = !PattenUtil.isAllDigits(valueStr.replaceAll(".", ""));
            } else {
                needBrackets = !PattenUtil.isAllDigits(valueStr);
            }
            sql += "DEFAULT " + (needBrackets ? ("(" + valueStr + ")") : (valueStr)) + " ";
        }
        sql+="USING "+tableColumnEntity.getName()+"::"+tableColumnEntity.getType();
        return sql;
    }


    /**
     * 删除字段
     * @param columnVo
     * @param tableName
     * @return
     */
    public static String deleteColumn(ColumnVo columnVo, String tableName){
        String sql = "alter table "+ tableName+" drop column "+columnVo.getColumnName() + "";
        return sql;
    }


}
